package jia.core.state;

import jia.game.AreaViewport;
import jia.game.CompassPanel;
import jia.game.ComponentUtils;
import jia.game.CoreGameFrame;
import jia.game.DialoguePanel;
import jia.game.FirstPersonViewport;
import jia.game.ImpotentLayoutManager;
import jia.game.MainButtonPanel;
import jia.game.ModuleInfoPanel;
import jia.game.PlayerCharacterList;
import jia.game.UiScroller;
import jia.game.Viewport;
import jia.game.GenericFlags;
import jia.core.GameStateManager;
import jia.core.InputProcessor;
import jia.core.UiManager;
import org.apache.log4j.Logger;

import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;

/**
 * Manager class for all things UI related.  This class keeps up with things like what panels
 * are shown, what cursor to use, and what to do when the player provides basic inputs.
 *
 * @author <a href="mailto:kintar@infinities-within.net">Kintar</a>
 */
public class BasicUiManager implements UiManager{
    private static final Logger log = Logger.getLogger(BasicUiManager.class);
    public static Cursor CUR_SWORD = null;
    protected InputProcessor inputProc;
    protected JComponent uiPanel;
    protected Viewport fpViewport;
    protected Viewport areaViewport;
    protected GameStateManager gameState;
    protected DialoguePanel dialoguePane;
    protected PlayerCharacterList characterList;
    protected MainButtonPanel btnPanel;
    protected CompassPanel compass;
    protected ModuleInfoPanel moduleInfo;





    private javax.swing.JPanel charlist;
    private javax.swing.JScrollPane dlgScroller;
    private javax.swing.JPanel farRight;
    private javax.swing.JButton jButton1;
    private javax.swing.JButton jButton2;
    private javax.swing.JButton jButton3;
    private javax.swing.JButton jButton4;
    private javax.swing.JButton jButton5;
    private javax.swing.JPanel tophalf;
    private javax.swing.JPanel viewportFrame;

    /**
     * Default contructor with no GameStateManager.
     * TODO:  Re-evaluate this contructor to determine necessity.
     */
    public BasicUiManager(){
        uiPanel = new CoreGameFrame();
        initCursors();
        initUiPanel();
    }
    
    /**
     * Constructor with a provided GameStateManager
     *
     * @param mgr
     */
    public BasicUiManager(GameStateManager mgr){
        //assign the passed GameStateManager to the local value
        this.gameState = mgr;
        //Create the core game frame.  This essentially defines what the background image will be.
        //TODO:  At some point allow the user to set what "skin" to use on a per game/module setting
        uiPanel = new CoreGameFrame();
        //Spark up the cursors
        initCursors();
        
        //load the various panels of the UI
        initUiPanel();
    }
    
    /**
     * Loads the custom cursors for the game.
     * TODO:  At some point allow the user to set the cursors in a game/module setting
     */
    protected void initCursors(){
        try {
            Image cursorImg = ImageIO.read(BasicUiManager.class.getClassLoader().getResource("cursors/swrdCrsr.png"));
            CUR_SWORD = Toolkit.getDefaultToolkit().createCustomCursor(cursorImg, new Point(0, 0), "Sword Cursor");
        } catch(Exception e) {
            if (GenericFlags.errorMessages){
                log.error(e.getMessage());
            }
            if (GenericFlags.warningMessages){
                log.warn("Couldn't load custom cursors for BasicUiManager");
            }
            CUR_SWORD = Cursor.getDefaultCursor();
        }
    }
    
    /**
     */
    protected void initUiPanel(){

        //set the skin image
        ((CoreGameFrame) uiPanel).setSkinImage("images/back3.gif");
        
        //set the cursors
        uiPanel.setCursor(CUR_SWORD);


        //Create the viewport
        fpViewport = new FirstPersonViewport();
        //create the area viewport.  this will not be visible unless the player hits a specific key
        areaViewport = new AreaViewport();
        //place the viewport in the upper left of the panel
        areaViewport.setSkinBorderInset(new Insets(15, 10, 10, 10));
        //areaViewport.setSkinImage("images/viewportFrame.gif");
        //areaViewport.setLocation(30, 15);
        //fpViewport.setSkinBorderInset(new Insets(15, 10, 10, 10));
        //fpViewport.setSkinImage("images/viewportFrame.gif");
        //fpViewport.setLocation(30, 15);

  
        //Since most layout managers wont work, we create our own that allows for absolute positioning
        //uiPanel.setLayout(new ImpotentLayoutManager());
        //uiPanel.add(fpViewport);
        
        //Create the character table that appears on the right hand side of the screen
        characterList = new PlayerCharacterList(gameState);
        UiScroller characterScroller = new UiScroller(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
        characterScroller.setSize(characterList.getWidth(), characterList.getHeight());
        characterScroller.getViewport().setBackground(ComponentUtils.getGlobalBackgroundColor());
        characterScroller.getViewport().add(characterList);
        characterScroller.setFocusable(false);
        //characterScroller.setLocation(250, 20);
        //uiPanel.add(characterScroller);
        
        //create the compass panel that shows the player what direction they are facing.
        compass = new CompassPanel();
        //compass.setLocation(250, 180);
        //uiPanel.add(compass);
        
        //beneath the character table this is some basic info about the module, (where they are, what time it is, etc)
        moduleInfo = new ModuleInfoPanel();
        //moduleInfo.setLocation(423, 180);
       // uiPanel.add(moduleInfo);
        
        //Create the dialogue panel where text interaction occurs
        dialoguePane = new DialoguePanel();
        dialoguePane.setCursor(CUR_SWORD);
        UiScroller diagScrl = new UiScroller(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
        diagScrl.setSize(dialoguePane.getWidth(), dialoguePane.getHeight());
        diagScrl.getViewport().setBackground(ComponentUtils.getGlobalBackgroundColor());
        diagScrl.getViewport().add(dialoguePane);
       // diagScrl.setLocation(30, 260);
        //uiPanel.add(diagScrl);
        
        //Create the common button collection that appears at the bottom of the screen
        btnPanel = new MainButtonPanel(800, 40);
        btnPanel.setBackground(new java.awt.Color(62, 43, 5));
        //btnPanel.setLocation(30, 500);
        //uiPanel.add(btnPanel);




        //***  NEW STUFF

        tophalf = new javax.swing.JPanel();
        viewportFrame = new javax.swing.JPanel();
        farRight = new javax.swing.JPanel();


        uiPanel.setBackground(new java.awt.Color(62, 43, 5));
        uiPanel.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
        uiPanel.setMaximumSize(new java.awt.Dimension(810, 580));
        uiPanel.setMinimumSize(new java.awt.Dimension(810, 580));
        uiPanel.setPreferredSize(new java.awt.Dimension(810, 580));

        tophalf.setBackground(new java.awt.Color(62, 43, 5));
        tophalf.setMaximumSize(new java.awt.Dimension(790, 377));
        tophalf.setMinimumSize(new java.awt.Dimension(790, 377));
        tophalf.setPreferredSize(new java.awt.Dimension(790, 377));

        viewportFrame.setBackground(new java.awt.Color(62, 43, 5));
        viewportFrame.setBorder(javax.swing.BorderFactory.createBevelBorder(javax.swing.border.BevelBorder.LOWERED));
        viewportFrame.setMaximumSize(new java.awt.Dimension(200, 235));
        viewportFrame.setMinimumSize(new java.awt.Dimension(200, 235));
        viewportFrame.setRequestFocusEnabled(false);
        viewportFrame.setVerifyInputWhenFocusTarget(false);

        fpViewport.setBackground(new java.awt.Color(0, 0, 0));
        fpViewport.setMaximumSize(new java.awt.Dimension(176, 209));
        fpViewport.setMinimumSize(new java.awt.Dimension(176, 209));

        org.jdesktop.layout.GroupLayout fpViewportLayout = new org.jdesktop.layout.GroupLayout(fpViewport);
        fpViewport.setLayout(fpViewportLayout);
        fpViewportLayout.setHorizontalGroup(
            fpViewportLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(0, 176, Short.MAX_VALUE)
        );
        fpViewportLayout.setVerticalGroup(
            fpViewportLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(0, 209, Short.MAX_VALUE)
        );

        org.jdesktop.layout.GroupLayout viewportFrameLayout = new org.jdesktop.layout.GroupLayout(viewportFrame);
        viewportFrame.setLayout(viewportFrameLayout);
        viewportFrameLayout.setHorizontalGroup(
            viewportFrameLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(viewportFrameLayout.createSequentialGroup()
                .addContainerGap()
                .add(fpViewport, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                .addContainerGap())
        );
        viewportFrameLayout.setVerticalGroup(
            viewportFrameLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(org.jdesktop.layout.GroupLayout.TRAILING, viewportFrameLayout.createSequentialGroup()
                .addContainerGap()
                .add(fpViewport, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        farRight.setBackground(new java.awt.Color(62, 43, 5));
        farRight.setBorder(javax.swing.BorderFactory.createBevelBorder(javax.swing.border.BevelBorder.LOWERED));
        farRight.setMaximumSize(new java.awt.Dimension(568, 235));
        farRight.setMinimumSize(new java.awt.Dimension(568, 235));
        farRight.setPreferredSize(new java.awt.Dimension(568, 235));

        characterList.setBackground(new java.awt.Color(0, 0, 0));
        characterList.setBorder(javax.swing.BorderFactory.createEtchedBorder());
        characterList.setMaximumSize(new java.awt.Dimension(544, 135));
        characterList.setMinimumSize(new java.awt.Dimension(544, 135));

        org.jdesktop.layout.GroupLayout characterListLayout = new org.jdesktop.layout.GroupLayout(characterList);
        characterList.setLayout(characterListLayout);
        characterListLayout.setHorizontalGroup(
            characterListLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(0, 538, Short.MAX_VALUE)
        );
        characterListLayout.setVerticalGroup(
            characterListLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(0, 131, Short.MAX_VALUE)
        );

        moduleInfo.setBackground(new java.awt.Color(0, 0, 0));
        moduleInfo.setBorder(javax.swing.BorderFactory.createEtchedBorder());
        moduleInfo.setMaximumSize(new java.awt.Dimension(372, 68));
        moduleInfo.setMinimumSize(new java.awt.Dimension(372, 68));

        org.jdesktop.layout.GroupLayout moduleInfoLayout = new org.jdesktop.layout.GroupLayout(moduleInfo);
        moduleInfo.setLayout(moduleInfoLayout);
        moduleInfoLayout.setHorizontalGroup(
            moduleInfoLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(0, 370, Short.MAX_VALUE)
        );
        moduleInfoLayout.setVerticalGroup(
            moduleInfoLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(0, 64, Short.MAX_VALUE)
        );

        compass.setMaximumSize(new java.awt.Dimension(162, 68));
        compass.setMinimumSize(new java.awt.Dimension(162, 68));
        compass.setPreferredSize(new java.awt.Dimension(162, 68));

        org.jdesktop.layout.GroupLayout compassLayout = new org.jdesktop.layout.GroupLayout(compass);
        compass.setLayout(compassLayout);
        compassLayout.setHorizontalGroup(
            compassLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(0, 162, Short.MAX_VALUE)
        );
        compassLayout.setVerticalGroup(
            compassLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(0, 68, Short.MAX_VALUE)
        );

        org.jdesktop.layout.GroupLayout farRightLayout = new org.jdesktop.layout.GroupLayout(farRight);
        farRight.setLayout(farRightLayout);
        farRightLayout.setHorizontalGroup(
            farRightLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(org.jdesktop.layout.GroupLayout.TRAILING, farRightLayout.createSequentialGroup()
                .addContainerGap()
                .add(farRightLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.TRAILING)
                    .add(characterList, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 542, Short.MAX_VALUE)
                    .add(farRightLayout.createSequentialGroup()
                        .add(moduleInfo, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                        .add(compass, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)))
                .addContainerGap())
        );
        farRightLayout.setVerticalGroup(
            farRightLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(org.jdesktop.layout.GroupLayout.TRAILING, farRightLayout.createSequentialGroup()
                .addContainerGap()
                .add(characterList, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(farRightLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(compass, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                    .add(moduleInfo, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
                .addContainerGap())
        );

        diagScrl.setBackground(new java.awt.Color(62, 43, 5));
        diagScrl.setBorder(javax.swing.BorderFactory.createBevelBorder(javax.swing.border.BevelBorder.LOWERED));

        dialoguePane.setBackground(new java.awt.Color(0, 0, 0));
        dialoguePane.setEditable(false);
        dialoguePane.setForeground(new java.awt.Color(255, 255, 255));
        dialoguePane.setText("dfasd\nasdfasd\nasdfasdf\nasdfasdf\nasdfasdf\nasdfasdf\nasdfasdf\nasdfasdf\nasdfasdf\nasdfasdf\nasdfasdf\nasdfasdf\nasdfasdf\nasdfasfd");
        dialoguePane.setFocusable(false);
        dialoguePane.setVerifyInputWhenFocusTarget(false);
        diagScrl.setViewportView(dialoguePane);
        //diagScrl.setViewportView(areaViewport);

        org.jdesktop.layout.GroupLayout tophalfLayout = new org.jdesktop.layout.GroupLayout(tophalf);
        tophalf.setLayout(tophalfLayout);
        tophalfLayout.setHorizontalGroup(
            tophalfLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(org.jdesktop.layout.GroupLayout.TRAILING, tophalfLayout.createSequentialGroup()
                .addContainerGap()
                .add(tophalfLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.TRAILING)
                    .add(org.jdesktop.layout.GroupLayout.LEADING, diagScrl, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 776, Short.MAX_VALUE)
                    .add(tophalfLayout.createSequentialGroup()
                        .add(viewportFrame, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.UNRELATED)
                        .add(farRight, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 566, Short.MAX_VALUE)))
                .addContainerGap())
        );
        tophalfLayout.setVerticalGroup(
            tophalfLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(tophalfLayout.createSequentialGroup()
                .addContainerGap()
                .add(tophalfLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(viewportFrame, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                    .add(farRight, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.UNRELATED)
                .add(diagScrl, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 258, Short.MAX_VALUE)
                .addContainerGap())
        );
/*
        
        btnPanel.setBorder(javax.swing.BorderFactory.createEtchedBorder());

        org.jdesktop.layout.GroupLayout btnPanelLayout = new org.jdesktop.layout.GroupLayout(btnPanel);
        btnPanel.setLayout(btnPanelLayout);
        btnPanelLayout.setHorizontalGroup(
            btnPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(0, 796, Short.MAX_VALUE)
        );
        btnPanelLayout.setVerticalGroup(
            btnPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(0, 50, Short.MAX_VALUE)
        );
*/
        btnPanel.setBackground(new java.awt.Color(62, 43, 5));
        org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(uiPanel);
        uiPanel.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(org.jdesktop.layout.GroupLayout.TRAILING, btnPanel, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
            .add(tophalf, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 800, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(org.jdesktop.layout.GroupLayout.TRAILING, layout.createSequentialGroup()
                .add(tophalf, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 530, Short.MAX_VALUE)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(btnPanel, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
        );



    }
    
    /**
     */
    public void setAreaViewState(){
        viewportFrame.remove(fpViewport);
        viewportFrame.add(areaViewport);
        viewportFrame.repaint();
    }
    
    /**
     */
    public void setStandardViewState(){
        viewportFrame.remove(areaViewport);
        viewportFrame.add(fpViewport);
        viewportFrame.repaint();
    }
    
    /**
     * @see net.sf.jia.core.UiManager#registerInputProcessor(net.sf.jia.core.InputProcessor)
     */
    public void registerInputProcessor(InputProcessor ip){
        inputProc = ip;
    }
    
    /**
     * @see net.sf.jia.core.UiManager#notifyNeedUpdate()
     */
    public void notifyNeedUpdate(){
        if(GenericFlags.debugMessages) {
            log.debug("Notified of needed update.");
        }
        fpViewport.updateGameState(gameState);
        areaViewport.updateGameState(gameState);
        characterList.updateGameState(gameState);
        btnPanel.updateGameState(gameState);
        compass.updateGameState(gameState);
        moduleInfo.updateGameState(gameState);
    }
    
    /**
     * @see net.sf.jia.core.UiManager#getUiPanel()
     */
    public JComponent getUiPanel(){
        return uiPanel;
    }
    
    /**
     * @return
     */
    public DialoguePanel getDialoguePane(){
        return dialoguePane;
    }
    
    /**
     * @return
     */
    public PlayerCharacterList getCharacterList(){
        return characterList;
    }
    
    /**
     * @return
     */
    public MainButtonPanel getButtonPanel(){
        return btnPanel;
    }
    
    /**
     * @return
     */
    public CompassPanel getCompassPanel(){
        return compass;
    }
    
    public ModuleInfoPanel getModuleInfoPanel(){
        return moduleInfo;
    }
    
    /**
     * Convenience method to give direct hook into setting the dialog panels
     * text value.  (Basically I got tired of typing .get().get().set(), etc...)
     *
     * @param text
     */
    public void setDialogText(String text){
        //this.dialoguePane.setText(this.dialoguePane.getText() + "\r\n" + text);
        this.dialoguePane.setText(text);
    }
    
    /**
     * @see net.sf.jia.core.UiManager#registerGameState(net.sf.jia.core.GameStateManager)
     */
    public void registerGameState(GameStateManager gs){
        gameState = gs;
    }
}
